﻿#region License
// Copyright 2007-2008 Rory Plaire (codekaizen@gmail.com)
/*
 * This license governs use of the accompanying software. If you use the software, you
 * accept this license. If you do not accept the license, do not use the software.
 * 
 * 1. Definitions
 * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
 * same meaning here as under U.S. copyright law.
 * A "contribution" is the original software, or any additions or changes to the software.
 * A "contributor" is any person that distributes its contribution under this license.
 * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
 * 
 * 2. Grant of Rights
 * (A) Copyright Grant- Subject to the terms of this license, including the license conditions 
 *     and limitations in section 3, each contributor grants you a non-exclusive, worldwide, 
 *     royalty-free copyright license to reproduce its contribution, prepare derivative works 
 *     of its contribution, and distribute its contribution or any derivative works that you create.
 * (B) Patent Grant- Subject to the terms of this license, including the license conditions and 
 *     limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free 
 *     license under its licensed patents to make, have made, use, sell, offer for sale, import, 
 *     and/or otherwise dispose of its contribution in the software or derivative works of the 
 *     contribution in the software.
 * 
 * 3. Conditions and Limitations
 * (A) No Trademark License- This license does not grant you rights to use any contributors' 
 *     name, logo, or trademarks.
 * (B) If you bring a patent claim against any contributor over patents that you claim are 
 *     infringed by the software, your patent license from such contributor to the software 
 *     ends automatically.
 * (C) If you distribute any portion of the software, you must retain all copyright, patent, 
 *     trademark, and attribution notices that are present in the software.
 * (D) If you distribute any portion of the software in source code form, you may do so only under 
 *     this license by including a complete copy of this license with your distribution. If you 
 *     distribute any portion of the software in compiled or object code form, you may only do so 
 *     under a license that complies with this license.
 * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no 
 *     express warranties, guarantees or conditions. You may have additional consumer rights under 
 *     your local laws which this license cannot change. To the extent permitted under your local laws, 
 *     the contributors exclude the implied warranties of merchantability, fitness for a particular 
 *     purpose and non-infringement.
 * 
 */
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace NPack.Numeric.Interfaces
{
    /// <summary>
    /// Defines a vector buffer for storing vector data in a specific format.
    /// </summary>
    /// <typeparam name="TVector">The type of vector to store.</typeparam>
    /// <typeparam name="TComponent">The type of component in the vector.</typeparam>
    /// <remarks>
    /// <para>
    /// A vector buffer allows specific storage of vectors in memory. This is useful
    /// since modern hardware treats vector data specially, and a specific storage
    /// format can take advantage of these capabilities. For example, SSE and SSE2 instructions
    /// are found on almost all of the non-embedded, general-purpose CPUs on the market,
    /// and these instructions work best when memory is aligned to 16-byte boundaries. 
    /// Using a Structure of Arrays (SoA) data format is also preferable when performing
    /// matrix computations.
    /// </para>
    /// </remarks>
    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
    public interface IVectorBuffer<TComponent, TVector> : IEnumerable<TVector>, IComparer<TVector>
        //where TComponent : IEquatable<TComponent>, IComparable<TComponent>,
        //                   IComputable<TComponent>, IConvertible, IFormattable
        where TVector : IBufferedVector<TComponent, TVector>, 
                        IEquatable<TVector>, IComparable<TVector>, 
                        IComputable<Double, TVector>
    {
        TVector Add(TComponent v0, TComponent v1);
        TVector Add(TComponent v0, TComponent v1, TComponent v2);
        TVector Add(TComponent v0, TComponent v1, Object context);
        TVector Add(TComponent v0, TComponent v1, TComponent v2, Object context);
        TVector Add(params TComponent[] components);
        TVector Add(Object context, params TComponent[] components);
        Int32 Add(IVector<TComponent> vector);
        Int32 Add(IVector<TComponent> vector, Object context);
        Int32 Add(TVector vector);
        void Clear();
        Boolean Contains(IVector<TComponent> item);
        Boolean Contains(TVector item);
        void CopyTo(TVector[] array, Int32 startIndex, Int32 endIndex);
        Int32 Count { get; }
        Boolean Find(TComponent v0, TComponent v1, out Int32 id);
        Boolean Find(TComponent v0, TComponent v1, TComponent v2, out Int32 id);
        //IVectorFactory<TComponent, TVector> Factory { get; }
        Int32 GetVectorLength(Int32 index);
        Boolean IsReadOnly { get; }
        Int32 MaximumSize { get; set; }
        void Remove(Int32 index);
        event EventHandler SizeIncreased;
        event CancelEventHandler SizeIncreasing;
        TVector this[Int32 index] { get; set; }
        //Int32 VectorLength { get; }
        event EventHandler<VectorOperationEventArgs<TComponent, TVector>> VectorChanged;
        VectorComparison ComparisonMode { get; set; }
        Int32 Compare(TVector a, TVector b, VectorComparison type);
        IVectorIndex<TComponent> Index { get; set; }
    }

    public enum VectorComparison
    {
        Lexicographic,
    }
}